/**
 * \file SCase.h
 * \author Catalin BLAJ
 * \author Vincent JACQUEMIN
 * \date 17 Octobre 2013
 *
 * Fichier header SCase.h pour le programme du Sudoku.
 */


#ifndef SCASE_H
#define SCASE_H

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdbool.h>
#include <assert.h>

#include "Outils.h"

/*----------------
|   STRUCTURE    |
----------------*/

/* ENUMERATION */

/**
 * \enum Modes
 * \brief Enumérations des états d'une case.
 *
 * Cette énumération liste les différents états possibles d'une case.
 */
typedef enum Etat
{
    /** Vide : Rien dans la case. */
    vide,
    /** Validée : L'utilisateur a rentré un nombre. */
    valide,
    /** Gelée : Un révélé est dans la case. */
    gele
} Etat;


/* STRUCTURE */

/**
* \struct SCase
* \brief Structure d'une case de Sudoku.
*
* Ceci est la structure d'une case de Sudoku.
*/
typedef struct SCase
{
    /** Entier représentant le type de Sudoku. */
    unsigned char type;
    /** Valeur de la case (seulement si elle est validée). */
    short valeur;
    /** Numéro de la case (naturellement de gauche à droite et de haut en bas). */
    unsigned int indice;
    /** Nombre permettant de savoir quels candidats sont encore en course pour la case.
     *  Il est compris entre 0 et 511 (2^(n²) possibilités car il y a n² candidats possibles.
     *  Si le Sudoku est de type 3, il y a 9 candidats possibles. */
    unsigned int candidats;
    /** Variable de type Modes qui renseignera l'état de la case (vide, validée ou gelée). */
    Etat etat;
} SCase;



/*-------------------
|     FONCTIONS     |
-------------------*/

/* INITIALISATION - TESTAMENT */

/**
 * \brief Initialiseur de SCase.
 * \param type : Type de sudoku (donnée).
 * \param indice : Indice de la case (donnée).
 * \return Renvoie la case initialisée.
 *
 * Initialiseur de SCase vide
 */
SCase* SC_initialiser(unsigned char type, unsigned int indice);

/**
 * \brief Testament de SCase.
 * \param maCase : Case du Sudoku que l'on veut détruire (donnée-résultat).
 *
 * Testament de SCase.
 */
void SC_testament(SCase* maCase);


/* ACCESSEURS */

/**
 * \brief Accesseur du type de Sudoku.
 * \param maCase : Case du Sudoku dont on veut connaitre le type (donnée).
 * \return Renvoie le type de Sudoku.
 *
 * Cette fonction permet d'accéder au type de Sudoku dont fait partie la case.
 */
unsigned char SC_getType(const SCase* maCase);

/**
 * \brief Accesseur de la variable valeur d'une case.
 * \param maCase : Case dont on veut connaître la valeur (donnée).
 * \return Renvoie la valeur de la case.
 *
 * Cette fonction permet d'accéder à la valeur d'une case.
 */
short SC_getValeur(const SCase* maCase);

/**
 * \brief Accesseur de la variable indice d'une case.
 * \param maCase : Case dont on veut connaître le indice (donnée).
 * \return Renvoie l'indice de la case.
 *
 * Cette fonction permet d'accéder à l'indice d'une case.
 */
unsigned SC_getIndice(const SCase* maCase);

/**
 * \brief Accesseur de la variable etat d'une case.
 * \param maCase : Case dont on veut connaître l'état (donnée).
 * \return Renvoie l'état de la case.
 *
 * Cette fonction permet d'accéder à l'état d'une case.
 */
Etat SC_getEtat(const SCase* maCase);

/**
 * \brief Accesseur d'un candidat d'une case.
 * \param maCase : Case que l'on veut tester (donnée).
 * \param candidat : Candidat que l'on veut déterminer (donnée).
 * \return Renvoie vrai si le candidat se trouve dans la case, faux sinon.
 *
 * Cette fonction permet de tester si un candidat se trouve dans une case.
 */
bool SC_getCandidat(const SCase* maCase, unsigned short candidat);

/**
 * \brief Accesseur de tous les candidats d'une case.
 * \param maCase : Case dont on veut connaître les candidats (donnée).
 * \return Renvoie un nombre correspondant à tous les candidats d'une case.
 *
 * Cette fonction permet de connaitre tous les candidats d'une case.
 */
unsigned int SC_getTousCandidats(const SCase* maCase);

/**
 * \brief Accesseur du nombre de candidats d'une SCase.
 * \param maCase : Case dont on veut connaître le nombre de candidats (donnée).
 * \return Renvoie le nombre de candidats de la case.
 *
 * Cette fonction permet de connaître le nombre de candidats d'une case.
 */
unsigned short SC_getNombreCandidats(const SCase* maCase);


/* MUTATEURS */

/**
 * \brief Mutateur de la variable valeur d'une case.
 * \param maCase : Case à modifier (donnée-résultat).
 * \param valeur : La nouvelle valeur de la case.
 *
 * Cette fonction permet de modifier la valeur d'une case.
 */
void SC_setValeur(SCase* maCase, short valeur);

/**
 * \brief Mutateur de la variable etat d'une case.
 * \param maCase : Case à modifier (donnée-résultat).
 * \param etatCase : Le nouvel état de la case.
 *
 * Cette fonction permet de modifier l'état d'une case.
 */
void SC_setEtat(SCase* maCase, Etat etatCase);

/**
 * \brief Mutateur de la variable candidats d'une case.
 * \param maCase : Case à modifier (donnée-résultat).
 * \param candidat : Le candidat à retirer (donnée).
 *
 * Cette fonction permet de retirer un candidat d'une case.
 */
void SC_retirerCandidat(SCase* maCase, unsigned short candidat);

/**
 * \brief Mutateur de la variable candidats d'une case.
 * \param maCase : Case à modifier (donnée-résultat).
 * \param candidat : Le candidat à ajouter (donnée).
 *
 * Cette fonction permet d'ajouter un candidat dans une case.
 */
void SC_ajouterCandidat(SCase* maCase, unsigned short candidat);

/**
 * \brief Mutateur de la variable candidats d'une case.
 * \param maCase : Case à modifier (donnée-résultat).
 *
 * Cette fonction permet de remettre tous les candidats dans une case.
 */
void SC_reinitialiserCandidats(SCase* maCase);

/**
 * \brief Mutateur de la variable candidats d'une case.
 * \param maCase : Case à modifier (donnée-résultat).
 * \param candidats : Nouvelle valeur de la variable candidats (donnée).
 *
 * Cette fonction permet de modifier librement la variable candidats.
 */
void SC_setCandidats(SCase* maCase, unsigned candidats);


/* SAUVEGARDE - CHARGEMENT */

/**
 * \brief Fonction permettant de créer une chaine pour sauvegarder une case.
 * \param maCase : Case à sauvegarder (donnée).
 * \return Renvoie la chaine créée.
 *
 * Cette fonction permet de sauvegarder une case.
 */
char* SC_toChaine(const SCase* maCase);

/**
 * \brief Fonction permettant de remplir une case grâce à une chaine de sauvegarde.
 * \param maCase : Case à traiter (donnée-résultat).
 * \param sauvegarde : La chaine de sauvegarde (donnée).
 *
 *  Met les bons champs dans la case en fonction de la chaine en paramètre.
 */
void SC_chargement(SCase* maCase, const char* sauvegarde);

#endif
